
#include "FocusServer.h"
#include "Util/util.h"
#include "Protocol/ProtocolApi.h"

using namespace Protocol;
FocusServer *FocusServer::s_FocusServer = nullptr;

using namespace Fdt;
int Speed = 100;//Speed默认值为100，代表快速；0代表慢速。

int REMOTE_CommandFocus(int act, int mode, int dir, int enable)
{
	return 0;
}   
int REMOTE_CommandPtz(int type, int dir, int enable, int speed)
{
	return 0;
}
int REMOTE_EnableZoom(int enable, int dir)
{
	return 0;
}
int MEDIA_CommonDigitalZoom(int x, int y, float base)
{
	return 0;
}
int MEDIA_CommonSaveOpticsZoom(int pos)
{
	return 0;
}
int MEDIA_CommonOpticsZoom(float base)
{
	return 0;
}
int REMOTE_GetZoomStep(int motor)
{
	return 0;
}
int MEDIA_CommonGetZoomInfo(int *x, int *y, float *digitalBase, float *opticsBase, int *focusPos)
{
	return 0;
}
int MEDIA_CommonSetFocus(int focusPos)
{
	return 0;
}

void FocusServerInit()
{
	FocusServer::instance();
}

FocusServer::FocusServer(){
	RegistRPC();
}

void FocusServer::RegistRPC(){
	RPCMethodMap method_map;

	method_map.emplace("SetMode", CRPCFuntion::CreateRpc([this](const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){
		return SetMode(request, inMap, response, outMap);
	}));

	method_map.emplace("GetMode", CRPCFuntion::CreateRpc([this](const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){
		return GetMode(request, inMap, response, outMap);
	}));

	method_map.emplace("SetZoomSpeedMode", CRPCFuntion::CreateRpc([this](const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){
		return SetZoomSpeedMode(request, inMap, response, outMap);
	}));

	method_map.emplace("GetZoomSpeedMode", CRPCFuntion::CreateRpc([this](const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){
		return GetZoomSpeedMode(request, inMap, response, outMap);
	}));

	method_map.emplace("Manual", CRPCFuntion::CreateRpc([this](const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){
		return ManualFocus(request, inMap, response, outMap);
	}));

	method_map.emplace("ManualZoom", CRPCFuntion::CreateRpc([this](const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){
		return ManualZoom(request, inMap, response, outMap);
	}));

	method_map.emplace("DigitalZoom", CRPCFuntion::CreateRpc([this](const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){
		return DigitalZoom(request, inMap, response, outMap);
	}));

	method_map.emplace("OpticsZoom", CRPCFuntion::CreateRpc([this](const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){
		return OpticsZoom(request, inMap, response, outMap);
	}));

	method_map.emplace("GetZoomInfo", CRPCFuntion::CreateRpc([this](const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){
		return GetZoomInfo(request, inMap, response, outMap);
	}));

	method_map.emplace("SetFocus", CRPCFuntion::CreateRpc([this](const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){
		return SetFocus(request, inMap, response, outMap);
	}));
	
	IProtocolInterface::GetInstance()->RegistProtocol("Focus", method_map);
}
bool FocusServer::SetMode(const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){
	std::string getStr;
	if(!Json::getJsonString(request, "Param.Mode", getStr)){
		response["data"]["Param"]["Result"] = false;
		return false;
	}

	tracef("get Mode %s", getStr.c_str());
	if (getStr == "Auto")
	{
		FocusServer::mode = 0;
	}
	else if(getStr == "Manual")
	{
		FocusServer::mode = 1;
	}
	else
	{
		response["data"]["Param"]["Result"] = false;
		return false;
	}
	REMOTE_CommandFocus(0, FocusServer::mode, 0, 0);
	
	response["data"]["Param"]["Result"] = true;
	return true;
}

bool FocusServer::GetMode(const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){

	if (FocusServer::mode == 0)
	{
		response["data"]["Param"]["Mode"] = "Auto";
	}
	else
	{
		response["data"]["Param"]["Mode"] = "Manual";
	}
	
	response["data"]["Param"]["Result"] = true;
	return true;
}

bool FocusServer::SetZoomSpeedMode(const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){
	std::string getStr;
	if(!Json::getJsonString(request, "Param.SpeedMode", getStr)){
		response["data"]["Param"]["Result"] = false;
		return false;
	}

	tracef("set ZoomSpeedMode %s", getStr.c_str());
	if (getStr == "Fast")
	{
		Speed = 100;
	}
	else if(getStr == "Slow")
	{
		Speed = 0;
	}
	else
	{
		response["data"]["Param"]["Result"] = false;
		return false;
	}
	
	response["data"]["Param"]["Result"] = true;
	return true;
}

bool FocusServer::GetZoomSpeedMode(const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){

	if (100 == Speed)
	{
		response["data"]["Param"]["SpeedMode"] = "Fast";
	}
	else
	{
		response["data"]["Param"]["SpeedMode"] = "Slow";
	}
	
	response["data"]["Param"]["Result"] = true;
	return true;
}


bool FocusServer::ManualFocus(const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){
	std::string getStr;
	if(!Json::getJsonString(request, "Param.Dir", getStr)){
		response["data"]["Param"]["Result"] = false;
		return false;
	}

	bool enable;
	if(!Json::getJsonBool(request, "Param.Enable", enable)){
		response["data"]["Param"]["Result"] = false;
		return false;
	}

	tracef("focus get Dir %s", getStr.c_str());
	tracef("focus get Enable %d", enable);

	int dir;
	if (getStr == "Far")
	{
		dir = 1;
	}
	else if (getStr == "Near")
	{
		dir = 0;
	}
	else
	{
	
		response["data"]["Param"]["Result"] = false;
		return false;
	}

	REMOTE_CommandFocus(1, 1, dir, enable);

	response["data"]["Param"]["Result"] = true;
	return true;
}

bool FocusServer::ManualZoom(const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){
	std::string getStr;
	if(!Json::getJsonString(request, "Param.Dir", getStr)){
		response["data"]["Param"]["Result"] = false;
		return false;
	}

	bool enable;
	if(!Json::getJsonBool(request, "Param.Enable", enable)){
		response["data"]["Param"]["Result"] = false;
		return false;
	}

	tracef("Zoom get Dir %s", getStr.c_str());
	tracef("Zoom get Enable %d", enable);

	if(!Json::getJsonInt(request, "Param.Speed",Speed)){
		response["data"]["Param"]["Result"] = false;
		//return false;
	}
	tracef("Zoom get Speed %d", Speed);

	int dir;
	if (getStr == "Out")
	{
		dir = 1;
	}
	else if (getStr == "In")
	{
		dir = 0;
	}
	else
	{
	
		response["data"]["Param"]["Result"] = false;
		return false;
	}

	if (100 == Speed)
	{
		REMOTE_EnableZoom(enable, dir?0:1);
	}
	else
	{
		REMOTE_CommandPtz(2, dir, enable, 0);
	}

	//REMOTE_CommandPtz(2, dir, enable, 0);
	//REMOTE_EnableZoom(enable, dir?0:1);

	response["data"]["Param"]["Result"] = true;
	return true;
}

bool FocusServer::DigitalZoom(const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){
	int x;
	if(!Json::getJsonInt(request, "Param.x", x)){
		response["data"]["Param"]["Result"] = false;
		return false;
	}

	int y;
	if(!Json::getJsonInt(request, "Param.y", y)){
		response["data"]["Param"]["Result"] = false;
		return false;
	}
	
	float base;
	if(!Json::getJsonFloat(request, "Param.base", base)){
		response["data"]["Param"]["Result"] = false;
		return false;
	}
	printf("base = %f\n",base);
	if (MEDIA_CommonDigitalZoom(x, y, base) < 0)
	{
		response["data"]["Param"]["Result"] = false;
		return false;
	}

	
	response["data"]["Param"]["Result"] = true;
	return true;
}

bool FocusServer::OpticsZoom(const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){	
	float base;
	if(!Json::getJsonFloat(request, "Param.base", base)){
		response["data"]["Param"]["Result"] = false;
		return false;
	}
	printf("base = %f\n",base);
	if (MEDIA_CommonOpticsZoom(base) < 0)
	{
		response["data"]["Param"]["Result"] = false;
		return false;
	}
	
	response["data"]["Param"]["Result"] = true;
	return true;
}

bool FocusServer::GetZoomInfo(const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){	
	int x;
	int y;
	int focusPos;
	float digitalBase;
	float opticsBase;
	
	if (MEDIA_CommonGetZoomInfo(&x, &y, &digitalBase, &opticsBase, &focusPos) < 0)
	{
		response["data"]["Param"]["Result"] = false;
		return false;
	}

	printf("x %d, y %d, digitalBase %f, opticsBase %f",x ,y ,digitalBase, opticsBase);
	response["data"]["Param"]["x"] = x;
	response["data"]["Param"]["y"] = y;
	response["data"]["Param"]["focusPos"] = focusPos;
	response["data"]["Param"]["digitalBase"] = digitalBase;
	response["data"]["Param"]["opticsBase"] = opticsBase;
	
	
	response["data"]["Param"]["Result"] = true;
	return true;
}

bool FocusServer::SetFocus(const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){	
	int focusPos;
	if(!Json::getJsonInt(request, "Param.pos", focusPos)){
		response["data"]["Param"]["Result"] = false;
		return false;
	}

	if (FocusServer::mode == 0)
	{
		response["data"]["Param"]["Result"] = false;
		return false;
	}

	if (MEDIA_CommonSetFocus(focusPos) < 0)
	{
		response["data"]["Param"]["Result"] = false;
		return false;
	}
	
	response["data"]["Param"]["Result"] = true;
	return true;

}